package domain

import (
	"encoding/json"
	"fmt"
	"go-weixin/app/usercenter/model"
	"go-weixin/app/usercenter/rpc/internal/dao"
	"go-weixin/app/usercenter/rpc/internal/repo"
	"go-weixin/common/chendb"

	"github.com/zeromicro/go-zero/core/logx"
	"github.com/zeromicro/go-zero/core/stores/redis"
	"github.com/zeromicro/x/errors"
)

type UserDomain struct {
	userRepo repo.UserRepo
	roleRepo repo.RoleRepo
	cache    redis.Redis
}

func NewUserDomain(engine chendb.ChenDb, cache redis.Redis) *UserDomain {
	return &UserDomain{
		userRepo: dao.NewUserDao(engine),
		roleRepo: dao.NewRoleDao(engine),
		cache:    cache,
	}
}

func (u UserDomain) Register(name string, password string, phone string, open_id string, email string, country string, gender bool, activity bool) (*model.UserModel, error) {
	user := new(model.UserModel)
	user.Phone = phone
	user.Email = email
	user.Country = country
	user.Gender = gender
	user.Activity = activity
	affected, err := u.userRepo.Register(name, password, user)
	if err != nil {
		logx.Error(err)
		return nil, err
	}
	if affected == 0 {
		logx.Error("创建用户失败: 受影响的行数0")
		return nil, errors.New(400, "注册用户失败")
	}
	return user, nil
}

func (u UserDomain) UserExistByName(name string) error {
	has, err := u.userRepo.UserExistByName(name)
	if err != nil {
		logx.Error(err)
		return err
	}

	if has {
		logx.Error("用户名已经存在")
		return errors.New(400, "用户名已存在")
	}
	return nil
}

func (u UserDomain) UserUpdateExist(name string, email string, phone string, id int64) error {
	has, err := u.userRepo.UserUpdateExistByName(name, id)
	if err != nil {
		logx.Info(err)
		return err
	}
	if has {
		logx.Error("用户名已存在")
		return errors.New(400, "用户名已存在")
	}

	has, err = u.userRepo.UserUpdateExistByEmail(email, id)
	if err != nil {
		logx.Info(err)
		return err
	}
	if has {
		logx.Error("邮箱已存在")
		return errors.New(400, "邮箱已存在")
	}

	has, err = u.userRepo.UserUpdateExistByPhone(phone, id)
	if err != nil {
		logx.Info(err)
		return err
	}
	if has {
		logx.Error("手机号已存在")
		return errors.New(400, "手机号已存在")
	}
	return nil
}

func (u UserDomain) Login(name string, password string) (*model.UserModel, error) {
	user := &model.UserModel{}
	has, err := u.userRepo.Login(name, password, user)
	if err != nil {
		logx.Error(err)
		return nil, err
	}
	if !has {
		return nil, errors.New(400, "用户名或密码错误")
	}
	return user, nil
}

func (u UserDomain) UserUpdate(id int64, name string, phone string, email string, openId string, country string, gender bool, activity bool) error {
	user := &model.UserModel{
		Name:     name,
		Phone:    phone,
		Email:    email,
		OpenId:   openId,
		Country:  country,
		Gender:   gender,
		Activity: activity,
	}
	affected, err := u.userRepo.UserUpdate(id, user)
	if err != nil {
		logx.Info(err)
		return err
	}
	if affected == 0 {
		return errors.New(400, "用户修改失败")
	}
	return nil
}

func (u UserDomain) UserAddRoleExist(userId int64, roleId int64) error {
	// 是否存在角色
	has, err := u.roleRepo.RoleExistById(roleId)
	if err != nil {
		logx.Info(err)
		return err
	}
	if !has {
		return errors.New(400, "不存在的角色")
	}
	// 是否添加
	has, err = u.userRepo.UserAddRoleExist(userId, roleId)
	if err != nil {
		logx.Info(err)
		return err
	}

	if has {
		return errors.New(400, "用户已经添加了此角色")
	}
	return nil
}

func (u UserDomain) UserAddRole(userId int64, roleId int64) error {
	affected, err := u.userRepo.UserAddRole(userId, roleId)
	if err != nil {
		logx.Info(err)
		return err
	}
	if affected == 0 {
		return errors.New(400, "用户添加角色失败")
	}
	return nil
}

func (u UserDomain) UserUpdateRole(userId int64, oldRoleId int64, newRoleId int64) error {
	has, err := u.roleRepo.RoleExistById(newRoleId)
	if err != nil {
		logx.Info(err)
		return err
	}
	if !has {
		return errors.New(400, "不存在的角色")
	}
	has, err = u.userRepo.UserUpdateRoleExist(userId, newRoleId)
	if err != nil {
		logx.Info(err)
		return err
	}
	if has {
		return errors.New(400, "用户已经添加了此角色")
	}
	affected, err := u.userRepo.UserUpdateRole(userId, oldRoleId, newRoleId)
	if err != nil {
		logx.Info(err)
		return err
	}

	if affected == 0 {
		return errors.New(400, "用户修改角色失败")
	}
	return nil
}

func (u UserDomain) UserList(page int64) ([]model.UserModel, error) {
	limit := 10
	offset := 10 * (page - 1)
	userList := make([]model.UserModel, 0)
	err := u.userRepo.UserList(int64(limit), offset, &userList)
	if err != nil {
		return nil, err
	}
	fmt.Println(userList)
	return userList, nil
}

func (u UserDomain) UserDetail(id int64) (*model.UserModel, error) {
	user := new(model.UserModel)
	has, err := u.userRepo.GetUserById(id, user)
	if err != nil {
		return nil, err
	}
	if !has {
		return nil, errors.New(400, "获取用户失败")
	}
	return user, nil
}

func (u UserDomain) UserGetRole(id int64) ([]model.UserGetRoleGroup, error) {
	roleList := make([]model.UserGetRoleGroup, 0)
	err := u.userRepo.UserGetRole(id, &roleList)
	if err != nil {
		return nil, err
	}
	return roleList, nil
}

func (u UserDomain) UserGetPower(id int64) ([]model.PowerModel, error) {
	// 先获取redids缓存
	powerListStr, err := u.cache.Get(fmt.Sprintf("user_powers_%d", id))
	powerList := make([]model.PowerModel, 0)
	if err != nil {
		return nil, err
	}
	if powerListStr == "" {
		// 查询数据库
		err := u.userRepo.UserGetPower(id, &powerList)
		if err != nil {
			return nil, err
		}
		powerListByte, err := json.Marshal(powerList)
		if err != nil {
			return nil, err
		}
		// 添加缓存
		err = u.cache.Setex(fmt.Sprintf("user_powers_%d", id), string(powerListByte), 60)
		if err != nil {
			return nil, err
		}
	} else {
		// 返序列化
		err := json.Unmarshal([]byte(powerListStr), &powerList)
		if err != nil {
			return nil, err
		}
	}
	return powerList, nil
}
